package com.linln.wxapi;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.linln.modules.member.domain.*;
import com.linln.modules.member.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.linln.common.constant.AdminConst;
import com.linln.common.constant.NoticeTypeConst;
import com.linln.common.constant.UrlConst;
import com.linln.common.enums.ResultEnum;
import com.linln.common.enums.TypeEnum;
import com.linln.common.exception.ResultException;
import com.linln.common.utils.DateUtils;
import com.linln.common.utils.MD5;
import com.linln.common.utils.ResultVoUtil;
import com.linln.common.utils.ToolUtil;
import com.linln.common.vo.ResultVo;
import com.linln.modules.ad.domain.AdInfo;
import com.linln.modules.ad.service.AdInfoService;
import com.linln.modules.message.domain.MessageInfo;
import com.linln.modules.message.service.MessageInfoService;
import com.linln.modules.store.domain.Storeinfo;
import com.linln.modules.store.service.StoreinfoService;

import io.swagger.annotations.Api;

@Api(value="代理商列表")
@RestController
@RequestMapping("/wx/memberagent/{area}")
public class WxApiMemberAgentController {

	   @Autowired
	   private MemberAgentService agentService;
	   @Autowired
	   private MemberInfoService memberInfoService;
	   
	   @Autowired
	    private MemberInfoService memberService;
	   @Autowired
	    private MemberPayDayCountService memberPayDayCountService;
	    @Autowired
	    private MemberOrderService orderService;

	   
	   @Autowired
	   private MessageInfoService messageService;
	 
	   @Autowired
	   private StoreinfoService storeService;
	 
	   @Autowired
	   private AdInfoService adService;
	   @Autowired
	     private WxPayService wxPayService;
	     @Autowired
	     private MemberRefundService refundService;

	@Autowired
	private AgentContactService agentContactService;


	private static final String REFUND_SUCCESS = "SUCCESS";

	/**
	 * 获取当前区域的联系方式
	 */
	@RequestMapping("/areaContact")
	@ResponseBody
	public ResultVo areaContact(@PathVariable String area,HttpServletRequest request) {

		AgentContact agentContact=agentContactService.getByArea(area);
		// 3.执行登录，进入自定义Realm类中
		return ResultVoUtil.success(agentContact);
	}


	/**
	     * 实现登录
	     */
	    @PostMapping("/agent/login")
	    @ResponseBody
	    public ResultVo login(String username, String password,HttpServletRequest request) {
	        // 判断账号密码是否为空
	        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
	            throw new ResultException(ResultEnum.USER_NAME_PWD_NULL);
	        }

	         // 3.执行登录，进入自定义Realm类中
	        try {
	            MemberInfo info = memberInfoService.getByMobile(username);
	            HttpSession session=request.getSession();
	            session.setAttribute(AdminConst.AGENT_ROLE_NAME, info); 
	            String md5password=MD5.getMD5String(password);
	            
	            if (info.getPassword().equals(md5password)) {
	            	MemberAgent memberagentarea=new MemberAgent();
	            	MemberInfo member=new MemberInfo();
	            	member.setId(info.getId());
	            	memberagentarea.setMember(member);
	                ExampleMatcher matcher = ExampleMatcher.matching();
	                Example<MemberAgent> example = Example.of(memberagentarea, matcher);
	                List<MemberAgent>agentList=agentService.getList(example);
	                for(MemberAgent memberAgent:agentList) {
	                	if(memberAgent==null)continue;
	                	memberAgent.setMember(null); 
	                }
	                info.setAgentList(agentList);
	                return ResultVoUtil.success(info);
	            } else {
	                return ResultVoUtil.error("您不是代理商！");
	            }
	        } catch (LockedAccountException e) {
	            return ResultVoUtil.error("该账号已被冻结");
	        } catch (AuthenticationException e) {
	            return ResultVoUtil.error("用户名或密码错误");
	        }
	    }
	    
	    /**
	     * 
	     * @param model
	     * @param keyword 关键词
	     * @param type 类型
	     * @param userId 登陆用户id
	     * @return
	     */
	    @RequestMapping("/agent/index")
	    @ResponseBody
	    public ResultVo index(Model model,@PathVariable String area, String keyword,Integer type,Long userId,Integer pageNumber,Integer pageSize) {
        	 Map<String,Object> map=new HashMap<String,Object>();  

	        // 创建匹配器，进行动态查询匹配
	        if(type==TypeEnum.MESSAGE.getCode()) {
	        	  ExampleMatcher matcher = ExampleMatcher.matching();
	        	  MessageInfo baseinfo=new MessageInfo();
		        if(keyword!=null && !keyword.trim().equals("")) {
		        	matcher.withMatcher("title", match -> match.contains());
		  	       // baseinfo.setTitle(keyword);		        			        	  
	        	}
	  	        baseinfo.setMessageStatus(1);		        
		        baseinfo.setArea(area);  
		        Example<MessageInfo> example = Example.of(baseinfo, matcher);
		        Page<MessageInfo> list = messageService.getPageList(example,pageNumber,pageSize);
		        map.put("list", list.getContent());
	            map.put("pageNumber", list.getPageable().getPageNumber()+1);
	            map.put("pageSize", list.getPageable().getPageSize());

	        }else if(type==TypeEnum.STORE.getCode()) {
	        	Storeinfo baseinfo=new Storeinfo();
	        	  ExampleMatcher matcher = ExampleMatcher.matching();
		        if(keyword!=null  && !keyword.trim().equals("")) {
		        	matcher.withMatcher("store_name", match -> match.contains());
		  	        baseinfo.setStore_name(keyword);        			        	  
	        	}
	        	baseinfo.setStoreStatus(1);		        
		        baseinfo.setArea(area);  
		        Example<Storeinfo> example = Example.of(baseinfo, matcher);
		        Page<Storeinfo> list = storeService.getPageList(example,pageNumber,pageSize);
		        map.put("list", list.getContent());
	            map.put("pageNumber", list.getPageable().getPageNumber()+1);
	            map.put("pageSize", list.getPageable().getPageSize());
	        	
	        }else if(type==TypeEnum.AD.getCode()) {
	        	AdInfo baseinfo=new AdInfo();
	        	ExampleMatcher matcher = ExampleMatcher.matching();
			    baseinfo.setAdStatus(1);		        
		        baseinfo.setArea(area); 
		        Example<AdInfo> example = Example.of(baseinfo, matcher);
		        Page<AdInfo> list = adService.getPageList(example,pageNumber,pageSize);
		        map.put("list", list.getContent());
	            map.put("pageNumber", list.getPageable().getPageNumber()+1);
	            map.put("pageSize", list.getPageable().getPageSize());
	        	
	        }
            return ResultVoUtil.success(map);
	       
	    }
	    
	    
	    /**
	     * 下架消息 并将钱退回去
	     * @param model
	     * @param id
	     * @param type
	     * @return
	     */
	    @RequestMapping("/refundInfo")
	    @ResponseBody
	    public ResultVo refundInfo(Model model, Long id,Integer type,Long userId) {
	    	 if(type==TypeEnum.MESSAGE.getCode()) {
	    		return  refundMessage( model,  id, type, userId);
	    	 }else if(type==TypeEnum.STORE.getCode()) {
	    		return refundStore( model,  id, type, userId);
	    	 }else if(type==TypeEnum.AD.getCode()) {
	    		 return refundAd( model,  id, type, userId);
	    	 }else {
               return ResultVoUtil.error("暂不支持其他类型");

	    	 }
	    	
	    }
	    
	    
	    
	    public ResultVo refundMessage(Model model, Long id,Integer type,Long userId) {
	    	MessageInfo message=messageService.getById(id);
	    	if(messageService.updateMessageStatus(2, id)) {
	    		
	            	if(message.getIstop()==1 && message.getFee().doubleValue()>0) {//置顶的退款 其他的拒绝掉
	            		//拒绝的时候将费用退回给客户 申请退款
	                   WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()
	                           //订单号
	                           .outTradeNo(message.getOrderId())
	                           //退款订单号
	                           .outRefundNo(ToolUtil.getRandomString(16)) 
	                           //金额
	                           .totalFee(yuanToFee(new BigDecimal(message.getFee())))
	                           //退款金额
	                           .refundFee(yuanToFee(new BigDecimal(message.getFee())))
	                          
	                           //todo 回调地址
	                           .notifyUrl(UrlConst.REFUNDNOTICEURL)
	                           .build();
	                   WxPayRefundResult wxPayRefundResult;
	                   try {
	                       wxPayRefundResult = wxPayService.refund(refundInfo);
	                       //判断退款信息是否正确
	                       if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())
	                               && REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {
	                   		     saveRefund( message,userId);

	                        }
	                   } catch (WxPayException e) {
	                   	return ResultVoUtil.error("异常");
	                   }
	            	}else {
	            		saveRefund( message,userId);
	            	}
	            	
	            	
	    		
	         return ResultVoUtil.success("下架成功");

	    	}else {
	    		return ResultVoUtil.error("下架失败");
	    	}
	    	
	    }
	    public void saveRefund(MessageInfo message,Long agentId) {
	    	MemberRefund refund=new MemberRefund();
	       	refund.setAgentId(agentId);
	       	refund.setArea(message.getArea());
	       	refund.setContent("拒绝置顶信息");
	       	refund.setMoney(message.getFee());
	       	refund.setOrderCode(message.getOrderId());
	       	refund.setRefundmoney(message.getFee());
	       	refund.setRefundStatus(0);
	       	refund.setType(NoticeTypeConst.MESSAGE);
	       	refund.setTypeId(message.getId());
	       	refundService.save(refund);
	    }
	    
	    /**
	     * 1 块钱转为 100 分
	     * 元转分
	     *
	     * @param bigDecimal 钱数目
	     * @return 分
	     */
	    private int yuanToFee(BigDecimal bigDecimal) {
	        return bigDecimal.multiply(new BigDecimal(100)).intValue();
	    }

	    /**
	     * 时间
	     *
	     * @return 时间戳
	     */
	    private String createTimestamp() {
	        return Long.toString(System.currentTimeMillis() / 1000);
	    }
	    
	    
	    /**
	     * 下架  置顶的地方退款
	     * @param model
	     * @param id    

	     * @return
	     */
	   
	    public ResultVo refundStore(Model model, Long id,Integer type,Long userId) {
	        // 复制保留无需修改的数据
	    	Storeinfo store=storeService.getById(id);	    	  
	    	if(storeService.updateStoreStatus(2, id)) {
	            	if(store.getIstop()==1 && store.getFee().doubleValue()>0) {
	            		//拒绝的时候将费用退回给客户
	               	 //申请退款
	                   WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()
	                           //订单号
	                           .outTradeNo(store.getOrderId())
	                           //退款订单号
	                           .outRefundNo(ToolUtil.getRandomString(16)) 
	                           //金额
	                           .totalFee(yuanToFee(new BigDecimal(store.getFee())))
	                           //退款金额
	                           .refundFee(yuanToFee(new BigDecimal(store.getFee())))
	                          
	                           //todo 回调地址
	                           .notifyUrl(UrlConst.REFUNDNOTICEURL)
	                           .build();
	                   WxPayRefundResult wxPayRefundResult;
	                   try {
	                       wxPayRefundResult = wxPayService.refund(refundInfo);
	                       //判断退款信息是否正确
	                       if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())
	                               && REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {
	                       	saveRefund(store,userId);
	                        }
	                   } catch (WxPayException e) {
	                   	return ResultVoUtil.error("异常");
	                   }	
	            	}else {
	                   	saveRefund(store,userId);

	            	}
	            	
	            
	            return ResultVoUtil.success("审核成功");
	        	}else {
	        		return ResultVoUtil.error("审核失败");
	        	}
	     }
	    
	    
	    public void saveRefund(Storeinfo store,Long agentId) {
	    	MemberRefund refund=new MemberRefund();
	    	refund.setAgentId(agentId);
	    	refund.setArea(store.getArea());
	    	refund.setContent("拒绝用户创建商户");
	    	refund.setMoney(store.getFee());
	    	refund.setOrderCode(store.getOrderId());
	    	refund.setRefundmoney(store.getFee());
	    	refund.setRefundStatus(0);
	    	refund.setType(NoticeTypeConst.STORE);
	    	refund.setTypeId(store.getId());
	    	refundService.save(refund);
	    }
	    
	    
	    public void saveRefund(AdInfo ad,Long agentId) {
	    	MemberRefund refund=new MemberRefund();
	       	refund.setAgentId(agentId);
	       	refund.setArea(ad.getArea());
	       	refund.setContent("拒绝用户投放的广告");
	       	refund.setMoney(ad.getFee());
	       	refund.setOrderCode(ad.getOrderId());
	       	refund.setRefundmoney(ad.getFee());
	       	refund.setRefundStatus(0);
	       	refund.setType(NoticeTypeConst.AD);
	       	refund.setTypeId(ad.getId());
	       	refundService.save(refund);
	    }
	    
	    
	    
	    /**
	     * 审核
	     * @param model
	     * @param id

	     * @return
	     */
	    public ResultVo refundAd(Model model, Long id,Integer type,Long userId) {
	        // 复制保留无需修改的数据
	    	AdInfo ad=adService.getById(id);
	         
	    	if(adService.updateAdStatus(2, id)) {

	            	if(ad.getFee()!=null && ad.getFee().doubleValue()>0) {
	            		//拒绝的时候将费用退回给客户
	               	 //申请退款
	                   WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()
	                           //订单号
	                           .outTradeNo(ad.getOrderId())
	                           //退款订单号
	                           .outRefundNo(ToolUtil.getRandomString(16)) 
	                           //金额
	                           .totalFee(yuanToFee(new BigDecimal(ad.getFee())))
	                           //退款金额
	                           .refundFee(yuanToFee(new BigDecimal(ad.getFee())))
	                           //todo 回调地址
	                           .notifyUrl(UrlConst.REFUNDNOTICEURL)
	                           .build();
	                   WxPayRefundResult wxPayRefundResult;
	                   try {
	                       wxPayRefundResult = wxPayService.refund(refundInfo);
	                       //判断退款信息是否正确
	                       if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())
	                               && REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {
	                    	   saveRefund(ad,userId);
	                        }
	                   } catch (WxPayException e) {
	                   	return ResultVoUtil.error("异常");
	                   }	
	            	}else {
	             	   saveRefund(ad,userId);
	            	}
	            	
	             return ResultVoUtil.success("审核成功");
	        	}else {
	        		//
	        		return ResultVoUtil.error("审核失败");
	        	}
	     }
	    
	    
	    /**
	     * 实现统计
	     */
	    @RequestMapping(value = "/agent/tongji",method={RequestMethod.POST,RequestMethod.GET})
	    @ResponseBody
	    public ResultVo tongji(Model model,@PathVariable String area,HttpServletRequest request) {
	         // 3.执行登录，进入自定义Realm类中
	        try {
	          
	        	 //代理商查看实时数据 
	        	int membercount=memberService.getCountByAreaAndToday(area);
	        	int messagecount=messageService.getCountByAreaAndToday(area);
	        	int storecount=storeService.getCountByAreaAndToday(area);
	        	double allmoney=orderService.getSumByAreaAndToday(area);
	        	Map<String,Object> map=new HashMap<String,Object>();
	        	map.put("membercount", membercount);
	        	map.put("messagecount", messagecount);
	        	map.put("storecount", storecount);
	        	map.put("allmoney", allmoney);
	        	Date date=new Date();
	        	String startTime=DateUtils.getDateInfoString(date,-7);
	        	String endTime=DateUtils.getDateInfoString(date,-1);	        	
	        	Page<MemberPayDayCount> page=memberPayDayCountService.getPageList(startTime, endTime, area);
	        	String dateString[]=new String[7];
	        	Double  moneyString[]=new Double[7];
	        	
	        	for(int i=7;i>0;i--) {
	        		dateString[7-i]=DateUtils.getDateInfoString(date,-i);
	        		moneyString[7-i]=0d;
	        	}
	        	map.put("dateList", dateString);
	        	List<MemberPayDayCount> list=page.getContent();
	        	if(list!=null && list.size()>0) {
	        		for(int i=0;i<7;i++) {
		            	for(int j=0;j<list.size();j++) {
		            		if(dateString[i].equals(DateUtils.formatDate(list.get(j).getCreateDate()))){
		            			moneyString[i]=list.get(j).getNum();
		            		}
		            	}
		            }	
	        	}
	        	map.put("moneyList", moneyString);
	            return ResultVoUtil.success(map);
	        }
	         catch (Exception e) {
	            return ResultVoUtil.error("数据异常");
	        }
	    }
}


